package Mypackage.Lexer;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import gnu.trove.THashSet;
import java.util.Arrays;
import java.util.Set;
%%
%{
  private boolean myHighlightingMode;

	public PerlFlexLexer(boolean highlightingMode) {
		this((java.io.Reader)null);
		myHighlightingMode = highlightingMode;
	}


	public final CharSequence getBuffer(){
		return zzBuffer;
	}


%}
%class PerlFlexLexer
%implements FlexLexer
%public
%unicode
%function advance
%type IElementType
%eof{  return;
%eof}


LNUM =					[0-9]+
DNUM =					([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
EXPONENT_DNUM = 			(({LNUM}|{DNUM})[eE][+-]?{LNUM})
HNUM = 					"0x"[0-9a-fA-F]+
LABEL= 					[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
WHITESPACE = 				[ \n\r\t]+
TABS_AND_SPACES = 			[ \t]*
//TOKENS = 				[;:,.\[\]()|^&+-/*=%!~$<>?@]
ANY_CHAR = 				(.|[\n])
NEWLINE = 				("\r"|"\n"|"\r\n")

DOUBLE_QUOTES_CHARS = 			("{"*([^$\"\\{]|("\\"{ANY_CHAR}))|{DOUBLE_QUOTES_LITERAL_DOLLAR})

DECIMAL_INTEGER =                  [1-9][0-9]* | 0
HEX_INTEGER =                      0[xX][0-9a-fA-F]+
OCTAL_INTEGER =                    0[0-7]+
INTEGER_LITERAL =                  ({DECIMAL_INTEGER} | {HEX_INTEGER} | {OCTAL_INTEGER})

FLOATING_POINT_LITERAL1 =          [0-9]*"."[0-9]+{EXPONENT_PART}?
FLOATING_POINT_LITERAL2 =          [0-9]+{EXPONENT_PART}
EXPONENT_PART =                    [Ee][+-]?[0-9]+

FLOAT_LITERAL =                    {FLOATING_POINT_LITERAL1} | {FLOATING_POINT_LITERAL2}

LINE_COMMENT =              ("//" | "#") .*

//===================================================================
//==========================CASTS====================================
//===================================================================

CAST_BEGIN =                       "(" {TABS_AND_SPACES}
CAST_END =                         {TABS_AND_SPACES} ")"

%x ST_DOUBLE_QUOTES
%x ST_COMMENT

%%

<YYINITIAL>{
//=========================KEYWORDS==================================


	//   flow control
	"if"                               { return  (TestTokenTypes.IF); }
	"elseif"                           { return  (TestTokenTypes.ELSEIF); }
	"else"                             { return  (TestTokenTypes.ELSE); }
	"do"                               { return  (TestTokenTypes.DO); }
	"while"                            { return  (TestTokenTypes.WHILE); }
	"for"                              { return  (TestTokenTypes.FOR); }
	"foreach"                          { return TestTokenTypes.FOREACH; }


	//   functions
	"print"                            { return  (TestTokenTypes.PRINT); }
	"eval"                             { return  (TestTokenTypes.EVAL); }
	"exit"                             { return  (TestTokenTypes.EXIT); }
    "blablabla"                        { return  (TestTokenTypes.BLABLABLA); }


//========================OPERATORS===================================


	"++"                               { return  (TestTokenTypes.INCREMENT); }
	"--"                               { return  (TestTokenTypes.DECREMENT); }
	"-"                                { return  (TestTokenTypes.MINUS); }
	"+"                                { return  (TestTokenTypes.PLUS); }
	"==="                              { return  (TestTokenTypes.IDENTICAL); }
	"!=="                              { return  (TestTokenTypes.NOT_IDENTICAL); }
	"=="                               { return  (TestTokenTypes.EQUAL); }
	"!="                               { return  (TestTokenTypes.NOT_EQUAL); }
	"<>"                               { return  (TestTokenTypes.NOT_EQUAL); }
	"<<"                               { return  (TestTokenTypes.SHIFT_LEFT); }
	">>"                               { return  (TestTokenTypes.SHIFT_RIGHT); }
	"<="                               { return  (TestTokenTypes.LESS_OR_EQUAL); }
	">="                               { return  (TestTokenTypes.GREATER_OR_EQUAL); }
	">"                                { return  (TestTokenTypes.GREATER); }
	"<"                                { return  (TestTokenTypes.LESS); }
	">>="                              { return  (TestTokenTypes.SHIFT_RIGHT_ASGN); }
	"<<="                              { return  (TestTokenTypes.SHIFT_LEFT_ASGN); }
	"+="                               { return  (TestTokenTypes.PLUS_ASGN); }
	"-="                               { return  (TestTokenTypes.MINUS_ASGN); }
	"*="                               { return  (TestTokenTypes.MUL_ASGN); }
	"/="                               { return  (TestTokenTypes.DIV_ASGN); }
	"%="                               { return  (TestTokenTypes.REM_ASGN); }
	".="                               { return  (TestTokenTypes.CONCAT_ASGN); }
	"&="                               { return  (TestTokenTypes.BIT_AND_ASGN); }
	"|="                               { return  (TestTokenTypes.BIT_OR_ASGN); }
	"^="                               { return  (TestTokenTypes.BIT_XOR_ASGN); }
	"="                                { return  (TestTokenTypes.ASGN); }
	"@"                                { return  (TestTokenTypes.SILENCE); }
	"&"                                { return  (TestTokenTypes.BIT_AND); }
	"|"                                { return  (TestTokenTypes.BIT_OR); }
	"^"                                { return  (TestTokenTypes.BIT_XOR); }
	"."                                { return  (TestTokenTypes.CONCAT); }
	"&&"                               { return  (TestTokenTypes.AND); }
	"||"                               { return  (TestTokenTypes.OR); }
	","                                { return  (TestTokenTypes.COMMA); }
	"?"                                { return  (TestTokenTypes.QUEST); }
	"%"                                { return  (TestTokenTypes.REM); }
	"!"                                { return  (TestTokenTypes.NOT); }
	":"                                { return  (TestTokenTypes.COLON); }
	";"                                { return  (TestTokenTypes.SEMICOLON); }
	"*"                                { return  (TestTokenTypes.MUL); }
	"/"                                { return  (TestTokenTypes.DIV); }
	"=>"                               { return  (TestTokenTypes.HASH_ARRAY); }


	"["                                { return  (TestTokenTypes.LBRACKET); }
	"]"                                { return  (TestTokenTypes.RBRACKET); }
	"("                                { return  (TestTokenTypes.LPAREN); }
	")"                                { return  (TestTokenTypes.RPAREN); }

	"{"                                { return  (TestTokenTypes.LBRACE); }
	"}"                                { return  (TestTokenTypes.RBRACE); }
}

// structure

<YYINITIAL>{WHITESPACE} {
	return TestTokenTypes.WHITESPACE;
}

<YYINITIAL>"#" {
     return TestTokenTypes.COMMENT;
}

<ST_DOUBLE_QUOTES>"\"" {
	return TestTokenTypes.DOUBLE_QUOTE;
}

<YYINITIAL,ST_DOUBLE_QUOTES,ST_COMMENT>{ANY_CHAR} {
    return TestTokenTypes.ERROR;
}
